package testing;

import genetics.Evolver;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Random;
import java.util.Scanner;

import logic.English;
import logic.PlayfairCipher;
import logic.PlayfairKey;
import cruncher.TetragraphMap;
import cruncher.WordMap;

public class Test6 {

	/**
	 * @param args
	 */
	
	public static int[] churn = new int[] { 1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,8,8,9,9,9,9,10,10,10,10,10,11,11,11,11,12,12,12,12,13,13,14,14,15,15,16,16,16,16,17,17,18,18,19,19,20,21,21,22,23,23,24,25,26,27,28,29,30,31,33,34,37,39,41,43,48,57,60 };
	
	public static void main(String[] args) {
		PlayfairCipher cipher = new PlayfairCipher(new English(), "playfairexample");
		WordMap wm = new WordMap("english-dict.txt");
		TetragraphMap tetra = new TetragraphMap(cipher, "english-tetragraphs.txt");
		tetra.loadBinary("TetraLog_hank.bin");
		
		try {
			Scanner s = new Scanner(new File("cipher.txt"));
			
			String line = s.nextLine().toLowerCase();
			
			PlayfairKey.cipher = cipher;
			PlayfairKey.cipherText = line;
			PlayfairKey.wordMap = wm;
			PlayfairKey.tetraMap = tetra;
			wm.prepList(200);
			//wm.prepList(new String[] {"playfair", "cipher", "word", "phrase"} );
			
			/*
			Vector<PlayfairKey> initPop = new Vector<PlayfairKey>();
			for(int i = 0; i < 20000; ++i)
			{
				initPop.add(PlayfairKey.generateRandomKey(cipher.getLanguage()));
			}
			
			Evolver<PlayfairKey> ev = new Evolver<PlayfairKey>();
			ev.setPopulation(initPop);
			Vector<PlayfairKey> resPop = ev.doEvolution(20, 0, 0.76f);
			System.out.println("Remaining : " + resPop.size());
			
			PlayfairKey theKey = resPop.get(0);
			cipher.setKey(theKey);
			System.out.println(theKey);
			String dec = cipher.decipherString(line);
			System.out.println("Result : " + dec);
			
			wm.evaluateAndPrint(dec);
			*/
			PlayfairKey gBest = null;
			int gMax = 0;
			Random rnd = Evolver.getRnd();
			
			//for(int n = 0; n < 10; ++n)
			//{
				PlayfairKey key = PlayfairKey.generateRandomKey(new English());
				int lastScore = key.fitness();
				
				gBest = key;
				gMax = lastScore;
				//int same = 0;
				
				for(int i = 0; i < 2000000; ++i)
				{
					/*
					int newScore = key.adapt(100);
					System.out.println(i + ") Score : " + newScore);
					if(newScore < lastScore) break;
					if(newScore > lastScore)
						same = 0;
					else
						same++;
					
					if(same > 200) break;
					lastScore = newScore;
					*/
					PlayfairKey child = (PlayfairKey) key.clone();
					//int mutCount = rnd.nextInt(5) + 1;
					//for(int z = 0; z < mutCount; ++z) child.mutate();
					child.adapt(3);
					
					int childScore = child.fitness();
					int rnum = churn[rnd.nextInt(100)];
					if(childScore > lastScore - rnum)
					//if(childScore > lastScore)
					{
						key = child;
						lastScore = childScore;
					}
					
					if(childScore > gMax)
					{
						gMax = childScore;
						gBest = child;
					}
					
					//System.out.println("Score : " + lastScore);
					
					if(i % 1000 == 0)
					{
						cipher.setKey(gBest);
						String dec = cipher.decipherString(line);
						System.out.println("[" + i + "] (" + gMax + ") " + dec);
					}
				}
				
				cipher.setKey(key);
				System.out.println(key);
				String dec = cipher.decipherString(line);
				System.out.println("Result : " + dec);
				
				wm.evaluateAndPrint(dec);
				
				if(lastScore > gMax)
				{
					gMax = lastScore;
					gBest = key;
				}
			//}
			
			System.out.println("==================================");
			
			cipher.setKey(gBest);
			System.out.println(gBest);
			String dec2 = cipher.decipherString(line);
			System.out.println("Score  : " + gMax);
			System.out.println("Result : " + dec2);
			System.out.println("Correct: goingfishingontheriver");
			wm.evaluateAndPrint(dec2);
		} catch (FileNotFoundException e) {
		}
		//dm.printContent();
		
	}

}
